package cn.yiueil.advice;

import cn.yiueil.annotation.LogAnnotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

@Aspect
@Component
public class LogAdvice {
    private static final Logger logger;
    static {
        logger = LoggerFactory.getLogger(LogAdvice.class);
    }

    private final String execution  = "execution(* *..*Impl.*(..))";
    private final String within  = "within(*..service.impl.*)";

    @Around(value = "@annotation(cn.yiueil.annotation.LogAnnotation)")
    public Object logAdvice(ProceedingJoinPoint proceedingJoinPoint) throws NoSuchMethodException {
        String before = "";
        String after = "";
        String exception = "";
        Class<?> targetClass = proceedingJoinPoint.getTarget().getClass();
        Signature signature = proceedingJoinPoint.getSignature();
        if (signature instanceof MethodSignature) {
            MethodSignature ms = (MethodSignature) signature;
            Method declaredMethod = targetClass.getDeclaredMethod(ms.getName(), ms.getParameterTypes());
            if (declaredMethod.isAnnotationPresent(LogAnnotation.class)) {
                LogAnnotation declaredAnnotation = declaredMethod.getDeclaredAnnotation(LogAnnotation.class);
                before = declaredAnnotation.before();
                after = declaredAnnotation.after();
                exception = declaredAnnotation.exception();
            }
        }

        logger.debug(before);
        Object proceed = null;
        try {
            proceed = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            logger.debug(exception);
            throwable.printStackTrace();
        }
        logger.debug(after);
        return proceed;
    }
}
